package wxk.interview.aop.core.cglib.interceptor;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 字节码生成技术      实现  MethodInterceptor接口，重写其 interceptor()方法
 * CGLib采用非常底层的字节码技术，可以为一个类创建子类，并在子类中采用方法拦截的技术拦截所有父类方法的调用，并顺势织入横切逻辑
 * <p>
 * 继承被代理对象，然后重写被代理的方法，在覆盖该方法时，插入自己的代码，
 * 因为需要重写被代理对象的方法，要求：被代理的方法不能使final方法，因为final方法不能被覆盖
 * <p>
 * 关于Spring中选择代理类型的判断
 * 如果通过ProxyFactory的setInterfaces(Class[] interfaces)指定针对接口进行代理，ProxyFactory就使用JdkDynamicAopProxy，如果是针对类的代理，则使用Cglib2AopProxy。另外，如果使用ProxyFactory的setOptimize(true)方法，则启动了优化代理方式，这样针对接口的代理也会使用Cglib2AopProxy。
 * <p>
 * 在引介增强中就需要强制指定为Cglib2AopProxy，因为引介增强是一种比较特殊的增强类型，不是在目标周围织入增强，而是为目标类创建新的方法和属性，所以引介增强的连接点事类级别的。而非方法级别的。
 *
 * @author wangxuekai
 * @version 1.0
 * @date 2017/3/5.
 */
public class CglibSimpleInterceptor implements MethodInterceptor {
    private Object target;

    public CglibSimpleInterceptor(Object target) {
        this.target = target;
    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("do some thing before----");
        // 执行目标对象方法
        Object result = method.invoke(target, objects);
        System.out.println("do some thing after-----");
        return result;
    }

    public Object getProxy() {
        //创建工具类
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(this.target.getClass());
        //设置回调方法
        enhancer.setCallback(this);
        //创建代理对象(子类)
        return enhancer.create();
    }


}
